package com.cndw.kungfu.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import com.cndw.commons.util.BlankUtils;
import com.cndw.kungfu.comm.PositionInspection;
import com.cndw.kungfu.comm.tencent.LogFieldType;
import com.cndw.kungfu.comm.tencent.QQDC;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsConfig;
import com.cndw.kungfu.config.ConstantsDayIntKey;
import com.cndw.kungfu.config.ConstantsLog;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.config.ConstantsRadio;
import com.cndw.kungfu.config.GoodsEffectConfig;
import com.cndw.kungfu.domain.GoodsMode;
import com.cndw.kungfu.domain.MonsterDeploy;
import com.cndw.kungfu.domain.Npc;
import com.cndw.kungfu.domain.Pendant;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Scene;
import com.cndw.kungfu.domain.Task;
import com.cndw.kungfu.domain.TaskMode;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.activity.ModeSceneWall;
import com.cndw.kungfu.model.activity.domain.WorldBoos;
import com.cndw.kungfu.model.battle.Team;
import com.cndw.kungfu.model.goods.PlayerBoxs;
import com.cndw.kungfu.model.goods.PlayerTrade;
import com.cndw.kungfu.model.scene.PendantManager;
import com.cndw.kungfu.model.scene.SceneManager;
import com.cndw.kungfu.model.scene.SearchResult;
import com.cndw.kungfu.model.scene.SubLineCore;
import com.cndw.kungfu.model.sys.LogServer;
import com.cndw.kungfu.model.task.PlayerTasks;
import com.cndw.kungfu.model.undercity.PlayerUndercity;
import com.cndw.kungfu.vo.PendantVO;
import com.cndw.kungfu.vo.ScenePlayerVO;
import com.cndw.rpg.annotation.Controller;
import com.cndw.rpg.framework.ResponseMessage;
import com.cndw.rpg.framework.Session;

/**
 * 场景处理,移动等
 * 
 * @author fantadust
 * 
 */
@Controller
public class SceneController {
	@Autowired
	private SceneManager sceneManager;
	@Autowired
	private PendantManager pendantManager;

	/**
	 * 进入场景
	 * 
	 */
	public ResponseMessage enterScene(Session session, int sceneId, int newSubLine) {
		Map<String, Object> map = new HashMap<String, Object>();
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Scene scene = Context.getSceneServer().getSceneById(sceneId);
		boolean changeScene = false;
		PlayerUndercity playerUndercity = null;
		if (scene == null || sceneId == Constants.cityUnderRootId || sceneId == Constants.cityFarmRootId) {
			changeScene = true;
		} else if (scene.isCityUndercity()) {
			playerUndercity = Context.getUndercityServer().getPlayerUndercity(player.getPlayerId());
			if (playerUndercity == null) {
				changeScene = true;
			} else if (playerUndercity.isOpenScene(sceneId) == false) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.enterscene.cantincopy"));
			} else {
				playerUndercity.setNowSceneId(sceneId);// 设置当前所在场景,开启其他门
			}
		} else if (scene.isCityWall()) {// 塞外死亡一次，一分钟不能切换场景
			ModeSceneWall wall = ModeSceneWall.getPlayer(player.getPlayerId());
			if (BlankUtils.isBlank(wall)) {
				// player.setSceneId(0);// 容错
				changeScene = true;
				// return
				// ResponseMessage.ticpErrMsg(LanguageLib.get("scene.enterscene.cantinwold"));
			} else {
				int reqiredLevel = ConstantsModel.wallLevelReqired[sceneId - 5001];
				if (player.getLevel() < reqiredLevel) {
					return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.wall.sceneLevel", reqiredLevel));
				}
			}

		} else if (scene.isCityUnionWar()) {
			if (!TimeProcesser.isRange(ConstantsModel.siegeWeek, ConstantsModel.siegeTime[1], ConstantsModel.siegeTime[2])) {
				changeScene = true;
			} else if (player.getDataInfo().getLastSceneId() == 0) {
				changeScene = true;
			}
		}
		if (changeScene) {
			sceneId = 2;
			scene = Context.getSceneServer().getSceneById(sceneId);
		}
		if (scene == null) {
			player.setSceneId(0);// 容错
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.args"));
		}

		if (ConstantsConfig.isSysInspectScene() && !PositionInspection.checkScene(player, scene)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.position.scene"));
		}

		// 交易中取消
		if (player.stateContains(Constants.playerState128_trade)) {
			PlayerTrade trade = Context.getDataServer().getPlayerTradeMap().get(player.getPlayerId());
			trade.canelTrade(LanguageLib.get("market.trade.leaveScene"), player.getPlayerId());
		}

		if (player.getSceneId() != sceneId || (newSubLine != player.getSubLine() && newSubLine != 0)) {
			Context.getSceneServer().exitScene(session, scene);// 退出上次的场景
		}

		if (newSubLine > 0) {
			player.setSubLine(newSubLine);
		}
		int subLine = scene.makeSubLine(player);

		Team team = player.getTeam();
		if (team != null && team.isMaster(player.getPlayerId())) {
			team.broadcastMaster("SceneController", "enterScene", sceneId, subLine);
		}

		player.setSceneId(sceneId);// 给当前人场景id

		List<Npc> npcs = Context.getSceneServer().getNpcBySceneId(sceneId);
		map.put("scene", scene.toSceneVO());
		map.put("subLine", player.getSubLine());
		map.put("npcs", npcs);
		map.put("pendants", pendantManager.getPendants(sceneId));
		if (player.getX() == 0 || sceneId == 5) {// 塞外场景特殊处理
			player.setX(scene.getBirthPoint()[0]);
			player.setY(scene.getBirthPoint()[1]);
		}
		map.put("playerX", player.getX());
		map.put("playerY", player.getY());

		if (scene.isCityMain() == false) {
			List<MonsterDeploy> monsterDeploys = Context.getCacheCenter().getMonsterDeploysBySceneId(sceneId);
			if (monsterDeploys != null) {
				Set<MonsterDeploy> passIds = null;
				for (MonsterDeploy e : monsterDeploys) {
					boolean isPass = false;
					if (e.getRefreshApp() > 0) {
						WorldBoos worldBoos = WorldBoos.getById(e.getRefreshApp());
						if (worldBoos == null || worldBoos.getBossFighter() == null) {
							isPass = true;
						}
					} else if (scene.isCityUndercity() && playerUndercity.isPassDeploy(e.getId())) {
						isPass = true;
					}
					if (isPass) {
						if (passIds == null) {
							passIds = new HashSet<MonsterDeploy>();
						}
						passIds.add(e);
					}
				}
				if (passIds != null && !passIds.isEmpty()) {
					List<MonsterDeploy> currentDeploys = new ArrayList<MonsterDeploy>(monsterDeploys);
					currentDeploys.removeAll(passIds);
					map.put("monsterDeploys", currentDeploys);
				} else {
					map.put("monsterDeploys", monsterDeploys);
				}

			}

		}
		scene.broadcast(player, player.toScenePlayerVO(), ConstantsRadio.sceneEnter);

		String idKey = Context.getSceneServer().getRadioKey(sceneId, subLine);
		Context.getTcpServer().addGroup(session, idKey);
		
		QQDC.getInstance().logClick(player, LogFieldType.scene);

		return ResponseMessage.getSuccMessage(map);

	}

	/**
	 * 加载分线数据
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage subLineNums(Session session) {
		Map<String, Object> map = new HashMap<String, Object>();
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Scene scene = Context.getSceneServer().getSceneById(player.getSceneId());
		if (scene == null || player == null) {
			return null;
		}
		if (!scene.openSubLine()) {
			return ResponseMessage.getSuccMessage(false);
		}
		map.put("subLine", player.getSubLine());
		map.put("subLineNums", SubLineCore.getMainSubLineNums());

		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 获取当前场景的玩家
	 * 
	 * @param session
	 * @param senceId
	 * @return
	 */
	public ResponseMessage getScenePlayers(Session session, int sceneId) {
		Scene scene = Context.getSceneServer().getSceneById(sceneId);
		if (scene == null) {
			return null;
		}
		Player sourcePlayer = Context.getPlayerServer().getByPlayerId(session.getUid());
		Collection<Long> currentIds = null;
		List<ScenePlayerVO> pList = new ArrayList<ScenePlayerVO>();
		if (scene.isCityUndercity()) {
			Team team = sourcePlayer.getTeam();
			if (team != null) {
				currentIds = team.getMemberIds();
			}
		}else if (scene.isSpecialBroadcast()) {
			currentIds = Context.getSceneServer().getOnSceneIds(sourcePlayer,scene);
		} else {
			currentIds = scene.getPlayerIds(sourcePlayer.getSubLine());
		}
		if (currentIds == null) {
			return null;
		}
		for (Long id : currentIds) {
			Player player = Context.getPlayerServer().getByPlayerId(id);
			if (player.getPlayerId() == sourcePlayer.getPlayerId()) {
				continue;
			} else if (player.getSceneId() != sceneId) {
				continue;// 针对客户端没执行退出的容错处理
			}
			ScenePlayerVO p = player.toScenePlayerVO();
			pList.add(p);
		}
		if (pList.size() <= 0) {
			return null;// 当前屏幕没有人
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("scenePlayers", pList);

		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 移动地图
	 */
	public ResponseMessage moveScene(Session session, int tx, int ty, int cx, int cy) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getSceneId() == 0 || player.getTs() > 0) {// 传送期间不允许移动
			return null;
		}
		if (ConstantsConfig.isSysInspectMove()) {
			if (cx == player.getX() || PositionInspection.checkMove(player, cx, cy)) {
				player.setX(cx);
				player.setY(cy);
				player.setTz(TimeProcesser.currentTimeMillis());
			} else {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.position.move"));
			}
		}
		player.setTx(tx);
		player.setTy(ty);
		Scene scene = Context.getSceneServer().getSceneById(player.getSceneId());
		if (scene == null) {
			return null;
		}
		scene.broadcast(player, new Object[] { session.getUid(), tx, ty }, ConstantsRadio.sceneMove);
		return null;
	}

	/**
	 * 走到地图
	 */
	public ResponseMessage moveOverScene(Session session, int x, int y, int sceneId) {

		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getSceneId() != sceneId || player.getTs() > 0) {
			return null;
		}

		if (ConstantsConfig.isSysInspectMove()) {
			if (player.getTz() == 0 || !PositionInspection.checkMove(player, x, y)) {
				// player.setTz(0);
				return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.position.move"));
			}
			// player.setTz(0);
		}
		player.setX(x);
		player.setY(y);
		player.setTx(0);
		player.setTy(0);
		return null;
	}

	/**
	 * 定点传送
	 * 
	 * @param session
	 * @param action
	 *            11 npc 12 玩家
	 * @param targetId
	 *            int性质目标id
	 * @param targetPlayerId
	 *            long 玩家id
	 * @return
	 */
	public ResponseMessage teleport(Session session, int action, int targetId, long targetPlayerId) {

		int goodsId = GoodsEffectConfig.sceneTeleportId;
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());

		Scene currentScene = Context.getSceneServer().getSceneById(player.getSceneId());
		if (currentScene.isCityUndercity()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.teleport.errcurrent"));
		}
		if (player.stateContains(Constants.playerState1024_aiUndercity)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("undercity.ai.err"));
		}
		boolean useGoods = true;
		boolean freeGoods = false;
		int KnightLevel  = player.getKnightTrueLevel();
		if (KnightLevel == 1 || KnightLevel == 4) {
			useGoods = false;
		}else if (KnightLevel == 2 || KnightLevel == 3) {
			int freeMax = KnightLevel == 2? 10 : 30;
			if ( freeMax - player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.freeTel) > 0 ) {
				useGoods = false;
				freeGoods = true;
			}
		}

		PlayerBoxs playerBoxs = player.getPlayerBoxs();
		if (useGoods && playerBoxs.getStackNum(goodsId) < 1) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.teleport.errgoods"));
		}
		SearchResult result = sceneManager.searchObject(action, targetId, targetPlayerId);
		if (result == null) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.search.err"));
		}
		int sceneId = result.getFianlSceneId();
		Scene scene = Context.getSceneServer().getSceneById(sceneId);
		if (!scene.isCityMain() && !scene.isCityField()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.teleport.err"));
		}
		boolean sameScene = false;
		if (result.getFianlSceneId() == player.getSceneId()) {
			if (result.getSubLine() == 0 || result.getSubLine() == player.getSubLine()) {
				sameScene = true;
			}
		}
		if (sameScene) {
			if (result.getX() > 0 && result.getY() > 0) {
				player.setX(result.getX());
				player.setY(result.getY());
			}
			scene.broadcast(player, new Object[] { session.getUid(), action, targetId, result.getX(), result.getY() }, ConstantsRadio.sceneTeleport);
		} else {
			if (result.getX() > 0 && result.getY() > 0) {
				player.setTx(result.getX());// 临时更新tx,ty
				player.setTy(result.getY());
			}
			player.setTs(result.getFianlSceneId());
		}
		if (useGoods) {
			playerBoxs.costGoods(goodsId, 1);
			LogServer.recordLog(player, ConstantsLog.goods, 70027, playerBoxs.getStackNum(goodsId));
		}
		if (freeGoods) {
			player.getDataInfo().getEveryDay().intDataAlter(ConstantsDayIntKey.freeTel, 1);
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("freeTel", player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.freeTel));
		map.put("result", result);
		
		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 按照目标寻路
	 * 
	 * @param session
	 * @param action
	 * @param targerId
	 * @return
	 */
	public ResponseMessage searchScene(Session session, int action, int targetId) {
		SearchResult result = sceneManager.searchObject(action, targetId, 0);
		if (result == null) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.search.err"));
		}
		if (result.getFinalSceneRootId() == Constants.cityUnderRootId) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.search.errtarget"));
		}

		return ResponseMessage.getSuccMessage(result);
	}

	/**
	 * 显示主城的子场景
	 * 
	 * @param session
	 * @param rootId
	 * @return
	 */
	public ResponseMessage showChild(Session session, int rootId) {
		if (rootId == 0 || rootId > 5) {
			return null;
		}
		Collection<Scene> scenes = Context.getCacheCenter().getAllScenes();

		List<Object[]> childList = new ArrayList<Object[]>();
		Scene scene = Context.getSceneServer().getSceneById(rootId);
		if (scene == null || !scene.isCityMain()) {
			return null;
		}
		childList.add(new Object[] { scene.getId(), scene.getName(), scene.getIcon() });
		for (Scene e : scenes) {
			if (e.getRootId() == rootId && e.isCityField()) {
				childList.add(new Object[] { e.getId(), e.getName(), e.getIcon() });
			}
		}
		return ResponseMessage.getSuccMessage(childList);
	}

	/**
	 * 显示场景上的信息
	 * 
	 * @param session
	 * @param sceneId
	 * @return
	 */
	public ResponseMessage showScene(Session session, int sceneId) {
		Scene scene = Context.getSceneServer().getSceneById(sceneId);
		if (scene == null || (!scene.isCityMain() && !scene.isCityField())) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		List<Npc> npcs = Context.getSceneServer().getNpcBySceneId(sceneId);
		List<MonsterDeploy> monsterDeploys = Context.getCacheCenter().getMonsterDeploysBySceneId(sceneId);

		if (!npcs.isEmpty()) {
			List<Object[]> npcMiniList = new ArrayList<Object[]>();
			for (Npc e : npcs) {
				npcMiniList.add(new Object[] { e.getId(), e.getName() });
			}
			map.put("npc", npcMiniList);
		}
		if (monsterDeploys != null && !monsterDeploys.isEmpty()) {
			List<Object[]> monsterList = new ArrayList<Object[]>();
			for (MonsterDeploy e : monsterDeploys) {
				if (e.getDefaultMonster() == null) {
					LogUtil.getMain().equals("err monster " + e.getId());
					continue;
				}
				monsterList.add(new Object[] { e.getDefaultMonster().id, e.getDefaultMonster().name, e.getDefaultMonster().level });
			}
			map.put("monsters", monsterList);
		}

		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 采集任务品
	 * 
	 * @param session
	 * @param id
	 * @return
	 */
	public ResponseMessage gatherPendant(Session session, int uniqueId) {

		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());

		PendantVO pendantVO = pendantManager.getPendantVO(uniqueId);
		if (pendantVO == null) {
			return null;
		}
		if (!PositionInspection.checkComm(player, pendantVO.getX(), pendantVO.getY(), 200)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.position.err"));
		}

		Pendant pendant = Context.getSceneServer().getpPendant(pendantVO.getId());
		if (pendant == null || pendant.getGainId() <= 0) {
			return null;
		}
		if (pendant.getTaskId() > 0) {
			PlayerTasks playerTasks = Context.getTaskServer().getPlayerTasks(player.getPlayerId());
			Task task = playerTasks.geTask(pendantVO.getTaskId());
			if (task == null || task.getStatus() != Task.STATUS_DOING) {
				return null;
			}
		}
		if (pendant.getGainId() <= 0) {
			return null;
		}
		GoodsMode mode = Context.getGoodsServer().getModeById(pendant.getGainId());
		if (mode == null) {
			return null;
		}
		int num = pendant.getGainNum();
		
		// 需要空格数
		int size = NumberProcesser.ceil(num, mode.getMaxStack());
		if (!player.getPlayerBoxs().checkBlack(size)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.player.boxmin", size));
		}
		Scene scene = Context.getSceneServer().getSceneById(player.getSceneId());
		if (scene.isCityWall()) {
			ModeSceneWall wall = ModeSceneWall.getPlayer(player.getPlayerId());
			if (!Context.getSceneServer().checkIsWallTime()) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.gatherPendant.time"));
			}

			if (!wall.checkPlayerActiveStatus()) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("scene.gatherPendant.active"));
			}
		}

		// 需要重新刷新的资源
		if (pendant.getTypeRefresh() == Pendant.refreshTypeShareD) {
			pendantManager.refreshPendantVO(player, pendantVO);
		}

		Context.getGoodsServer().giveGoods(player.getPlayerId(), pendant.getGainId(), num);

		// 添加"任务-采集任务物品"日志
		TaskMode taskModel = Context.getCacheCenter().getTaskModeById(pendant.getTaskId());
		if (taskModel != null) {
			LogServer.recordLog(player, ConstantsLog.task, 20004, taskModel.getName(), mode.getName(), num);
		} else {
			LogServer.recordLog(player, ConstantsLog.goods, 70023, mode.getName(), num, player.getPlayerBoxs().getStackNum(mode.getGoodsId()));
		}

		return ResponseMessage.getSuccMessage(true);
	}

}